package hn.sigit.interop.gmlproducers;

import hn.sigit.model.commons.IRRR;
import hn.sigit.model.commons.IResponsibility;
import hn.sigit.model.commons.IRestriction;
import hn.sigit.model.commons.IRight;

import java.util.ArrayList;
import java.util.List;

import org.deegree.commons.tom.TypedObjectNode;
import org.deegree.commons.tom.genericxml.GenericXMLElement;
import org.deegree.commons.tom.genericxml.GenericXMLElementContent;
import org.deegree.commons.tom.primitive.PrimitiveType;
import org.deegree.commons.tom.primitive.PrimitiveValue;
import org.deegree.feature.GenericFeature;
import org.deegree.feature.property.GenericProperty;
import org.deegree.feature.property.Property;
import org.deegree.feature.property.SimpleProperty;
import org.deegree.feature.types.GenericFeatureType;
import org.deegree.feature.types.property.ArrayPropertyType;
import org.deegree.feature.types.property.PropertyType;
import org.deegree.feature.types.property.SimplePropertyType;
import org.deegree.gml.GMLVersion;

public class RRRGMLProducer extends GMLProducer<IRRR> {
	private static final SimplePropertyType partyIdentityType = new SimplePropertyType(newQName("partyIdentity"), 1, 1, PrimitiveType.STRING, false, false, null);
	private static final SimplePropertyType partyNameType = new SimplePropertyType(newQName("partyName"), 1, 1, PrimitiveType.STRING, false, false, null);
	
	private static final SimplePropertyType rightTypeType = new SimplePropertyType(newQName("rightType"), 1, 1, PrimitiveType.STRING, false, false, null);
	private static final SimplePropertyType restrictionTypeType = new SimplePropertyType(newQName("restrictionType"), 1, 1, PrimitiveType.STRING, false, false, null);
	private static final SimplePropertyType responsibilityTypeType = new SimplePropertyType(newQName("responsibilityType"), 1, 1, PrimitiveType.STRING, false, false, null);
	
	private static final SimplePropertyType rrrDescType = new SimplePropertyType(newQName("rrrDesc"), 1, 1, PrimitiveType.STRING, false, false, null);
	private static final ArrayPropertyType shareType = new ArrayPropertyType(newQName("share"), 1, 1, false, false, null);
	
	private static final GenericFeatureType rightFeatureType;
	private static final GenericFeatureType restrictionFeatureType;
	private static final GenericFeatureType responsibilityFeatureType;
	
	static {
		rightFeatureType = buildRightFeatureType();
		restrictionFeatureType = buildRestrictionFeatureType();
		responsibilityFeatureType = buildResponsibilityFeatureType();
	}
	
	private static GenericFeatureType buildRightFeatureType() {
		List<PropertyType> propertyTypes = new ArrayList<PropertyType>();
		propertyTypes.add(partyIdentityType);
		propertyTypes.add(partyNameType);
		propertyTypes.add(rightTypeType);
		propertyTypes.add(rrrDescType);
		propertyTypes.add(shareType);

		return new GenericFeatureType(newQName("Right"), propertyTypes, false);
	}
	private static GenericFeatureType buildRestrictionFeatureType() {
		List<PropertyType> propertyTypes = new ArrayList<PropertyType>();
		propertyTypes.add(partyIdentityType);
		propertyTypes.add(partyNameType);
		propertyTypes.add(restrictionTypeType);
		propertyTypes.add(rrrDescType);
		propertyTypes.add(shareType);

		return new GenericFeatureType(newQName("Restriction"), propertyTypes, false);
	}
	private static GenericFeatureType buildResponsibilityFeatureType() {
		List<PropertyType> propertyTypes = new ArrayList<PropertyType>();
		propertyTypes.add(partyIdentityType);
		propertyTypes.add(partyNameType);
		propertyTypes.add(responsibilityTypeType);
		propertyTypes.add(rrrDescType);
		propertyTypes.add(shareType);

		return new GenericFeatureType(newQName("Responsibility"), propertyTypes, false);
	}
	
	public RRRGMLProducer(String jurisdictionCode, IRRR rrr) {
		super(jurisdictionCode, rrr);
	}
	
	@Override
	public GenericFeature buildFeature() {
		SimpleProperty partyId = new SimpleProperty(partyIdentityType, getObjectFeature().getParty().getExtParty().getFormalIdentity(), PrimitiveType.STRING);
		
		SimpleProperty partyName = new SimpleProperty(partyNameType, getObjectFeature().getParty().getExtParty().getName(), PrimitiveType.STRING);
		
		SimpleProperty rightType = null;
		SimpleProperty restrictionType = null;
		SimpleProperty responsibilityType = null;
		
		if (getObjectFeature() instanceof IRight)
			rightType = new SimpleProperty(rightTypeType, ((IRight)getObjectFeature()).getType().name(), PrimitiveType.STRING);
		else if (getObjectFeature() instanceof IRestriction)
			restrictionType = new SimpleProperty(restrictionTypeType, ((IRestriction)getObjectFeature()).getType().name(), PrimitiveType.STRING);
		else if (getObjectFeature() instanceof IResponsibility)
			responsibilityType = new SimpleProperty(responsibilityTypeType, ((IResponsibility)getObjectFeature()).getType().name(), PrimitiveType.STRING);
		else
			throw new IllegalArgumentException("No feature type for " + getObjectFeature().getClass().getCanonicalName());
		
		SimpleProperty rrrDesc = new SimpleProperty(rrrDescType, nvl(getObjectFeature().getDescription()), PrimitiveType.STRING);
		
		List<TypedObjectNode> numeratorChildren = new ArrayList<TypedObjectNode>();
		numeratorChildren.add(new PrimitiveValue(String.valueOf(getObjectFeature().getShare().getNumerator()), PrimitiveType.INTEGER));
		GenericXMLElement numerator = new GenericXMLElement(newQName("numerator"), new GenericXMLElementContent(null, null, numeratorChildren));
		
		List<TypedObjectNode> denominatorChildren = new ArrayList<TypedObjectNode>();
		denominatorChildren.add(new PrimitiveValue(String.valueOf(getObjectFeature().getShare().getDenominator()), PrimitiveType.INTEGER));
		GenericXMLElement denominator = new GenericXMLElement(newQName("denominator"), new GenericXMLElementContent(null, null, denominatorChildren));

		List<TypedObjectNode> shareChildren = new ArrayList<TypedObjectNode>();
		shareChildren.add(numerator);
		shareChildren.add(denominator);
		
		GenericProperty share = new GenericProperty(shareType, new GenericXMLElementContent(null, null, shareChildren));
		
		
		List<Property> propertyList = new ArrayList<Property>();
		propertyList.add(partyId);
		propertyList.add(partyName);
		
		GenericFeatureType gft = null;
		if (getObjectFeature() instanceof IRight) {
			propertyList.add(rightType);
			gft = rightFeatureType;
		}
		else if (getObjectFeature() instanceof IRestriction) {
			propertyList.add(restrictionType);
			gft = restrictionFeatureType;
		}
		else if (getObjectFeature() instanceof IResponsibility) {
			propertyList.add(responsibilityType);
			gft = responsibilityFeatureType;
		}

		propertyList.add(rrrDesc);
		propertyList.add(share);
		
		
		return new GenericFeature(gft, String.valueOf(getObjectFeature().getRID()), propertyList, GMLVersion.GML_31);
	}


}
